#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/sys.h>
#include <asm/system.h>

extern int system_call(void);

union task_union {
    struct task_struct task;
    char stack[PAGE_SIZE];
};

static union task_union init_task = {INIT_TASK, };

long startup_time = 0;

struct task_struct * task[NR_TASKS] = {&(init_task.task), };

long user_stack[PAGE_SIZE >> 2];

struct {
    long * a;
    short b;
} stack_start = {&user_stack[PAGE_SIZE >> 2], 0x10};

void sched_init(void)
{
    int i;
    struct desc_struct * p;
    
    if (sizeof(struct sigaction) != 16) {
        printk("Struct sigaction MUST be 16 bytes");
        while (1);
    }
    set_tss_desc(gdt + FIRST_TSS_ENTRY, &(init_task.task.tss));
    set_ldt_desc(gdt + FIRST_LDT_ENTRY, &(init_task.task.ldt));
    p = gdt + 2 + FIRST_TSS_ENTRY;
    for(i = 1; i < NR_TASKS; i++) {
        task[i] = NULL;
        p->a = p->b = 0;
        p++;
        p->a = p->b = 0;
        p++;
    }
    __asm__("pushfl\n\t"
        "andl $0xffffbfff, (%esp)\n\t"
        "popfl");
    ltr(0);
    lldt(0);
    set_system_gate(0x80, &system_call);
}
